package com.pxst.sys.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.pxst.resp.ApiResp;
import com.pxst.sys.entity.AuthorityEntity;
import com.pxst.sys.entity.RoleAuthorityEntity;
import com.pxst.sys.entity.UserRolesEntity;
import com.pxst.sys.req.AdminRoleReq;
import com.pxst.sys.resp.RoleAuthorityResp;
import com.pxst.sys.service.AuthorityService;
import com.pxst.sys.service.RoleAuthorityService;
import com.pxst.sys.service.UserRolesService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pxst.sys.entity.RoleEntity;
import com.pxst.sys.mapper.RoleMapper;
import com.pxst.sys.service.RoleService;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/** 
* @author yangxy
* @version 创建时间：2023年7月26日 下午12:53:43 
*/
@Service
@Transactional
public class RoleServiceImpl extends ServiceImpl<RoleMapper, RoleEntity> implements RoleService {

    @Autowired
    private RoleService roleService;

    @Autowired
    private RoleAuthorityService roleAuthorityService;

    @Autowired
    private UserRolesService userRolesService;

    @Autowired
    private AuthorityService authorityService;

    /**
     * 新增角色
     * @param adminRoleReq
     * @return
     */
    @Override
    public ApiResp create(AdminRoleReq adminRoleReq) {
        //先新增角色表数据
        RoleEntity roleEntity = new RoleEntity();
        //判断roleCode字段值要唯一
        List<RoleEntity> list = roleService.list(new LambdaQueryWrapper<RoleEntity>().eq(RoleEntity::getRoleCode, adminRoleReq.getRoleCode()));
        if (list.size() > 0){
            return ApiResp.bussError("角色编码已存在，请重新输入！");
        }
        BeanUtils.copyProperties(adminRoleReq,roleEntity,"id");
        roleService.save(roleEntity);
        Long roleId = roleEntity.getId();

        //再新增角色权限表信息
        // 创建一个新的集合用于存储处理后的结果
        List<String> resultList = new ArrayList<>();
        // 遍历 processedMap 中的键值对
        for (Map.Entry<String, String> entry : adminRoleReq.getPermissions().entrySet()) {
            String key = entry.getKey();
            String value = entry.getValue();
            // 将值以逗号分隔符拆分成多个字符串
            String[] values = value.split(",");
            // 将每个值与键以点号进行拼接，并添加到结果集合中
            for (String val : values) {
                String result = key + "." + val;
                resultList.add(result);
            }
        }
        //将集合中的authorityCode去查询权限表，得到对应的id，将id保存到角色权限表中
        List<Long> authorityIds = resultList.stream().map(iter -> {
            AuthorityEntity authority = authorityService.getOne(new LambdaQueryWrapper<AuthorityEntity>().eq(AuthorityEntity::getAuthorityCode, iter));
            return authority.getId();
        }).collect(Collectors.toList());

        for (Long authorityId : authorityIds) {
            RoleAuthorityEntity roleAuthority = new RoleAuthorityEntity();
            roleAuthority.setRoleId(roleId);
            roleAuthority.setAuthorityId(authorityId);
            roleAuthorityService.save(roleAuthority);
        }
        return ApiResp.sucess(roleService.getById(roleId));
    }

    /**
     * 修改角色
     * @param adminRoleReq
     * @return
     */
    @Override
    public ApiResp updateRole(AdminRoleReq adminRoleReq) {
        //通过传来的id进行查询，如果是超级管理员, 此角色不允许被修改及移除
        RoleEntity byId = roleService.getById(adminRoleReq.getId());
        if (byId.getSuperAdmin()==1){
            return ApiResp.bussError("超级管理员, 此角色不允许被修改及移除");
        }
        BeanUtils.copyProperties(adminRoleReq,byId,"roleCode");
        roleService.updateById(byId);
        if (adminRoleReq.getPermissions() != null){
            //需要修改角色权限表信息
            //先删除角色权限表中对应的信息
            roleAuthorityService.remove(new LambdaQueryWrapper<RoleAuthorityEntity>().eq(RoleAuthorityEntity::getRoleId, adminRoleReq.getId()));

            //再新增角色权限表信息
            // 创建一个新的集合用于存储处理后的结果
            List<String> resultList = new ArrayList<>();
            // 遍历 processedMap 中的键值对
            for (Map.Entry<String, String> entry : adminRoleReq.getPermissions().entrySet()) {
                String key = entry.getKey();
                String value = entry.getValue();
                // 将值以逗号分隔符拆分成多个字符串
                String[] values = value.split(",");
                // 将每个值与键以点号进行拼接，并添加到结果集合中
                for (String val : values) {
                    String result = key + "." + val;
                    resultList.add(result);
                }
            }
            //将集合中的authorityCode去查询权限表，得到对应的id，将id保存到角色权限表中
            List<Long> authorityIds = resultList.stream().map(iter -> {
                AuthorityEntity authority = authorityService.getOne(new LambdaQueryWrapper<AuthorityEntity>().eq(AuthorityEntity::getAuthorityCode, iter));
                return authority.getId();
            }).collect(Collectors.toList());

            for (Long authorityId : authorityIds) {
                RoleAuthorityEntity roleAuthority = new RoleAuthorityEntity();
                roleAuthority.setRoleId(byId.getId());
                roleAuthority.setAuthorityId(authorityId);
                roleAuthorityService.save(roleAuthority);
            }
        }
        return ApiResp.sucess();
    }

    /**
     * 删除角色
     * @param id
     * @return
     */
    @Override
    public ApiResp deleteRole(Long id) {
        //通过传来的id进行查询，如果是超级管理员, 此角色不允许被修改及移除
        RoleEntity byId = roleService.getById(id);
        if (byId == null){
            return ApiResp.bussError("未查询到相关角色信息，请检查");
        }
        if (byId.getSuperAdmin()==1){
            return ApiResp.bussError("超级管理员, 此角色不允许被修改及移除");
        }
        //查询正在使用该角色的用户，如果有用户不允许删除。
        List<UserRolesEntity> list = userRolesService.list(new LambdaQueryWrapper<UserRolesEntity>().eq(UserRolesEntity::getRoleId, id));
        if (list.size() > 0){
            return ApiResp.bussError("此角色有用户正在使用，不允许删除");
        }
        //删除角色和角色权限信息
        roleService.removeById(id);
        roleAuthorityService.remove(new LambdaQueryWrapper<RoleAuthorityEntity>().eq(RoleAuthorityEntity::getRoleId, id));
        return ApiResp.sucess();
    }

    /**
     * 查询角色权限
     * @param id
     * @param with
     * @return
     */
    @Override
    public RoleAuthorityResp permissionsList(Long id, String with) {
        //通过角色id查询到当前角色的信息和所有权限
        RoleEntity byId = roleService.getById(id);
        List<RoleAuthorityEntity> list = roleAuthorityService.list(new LambdaQueryWrapper<RoleAuthorityEntity>().eq(RoleAuthorityEntity::getRoleId, id));

        //获取当前角色的权限code集合
        List<Long> collect = list.stream().map(RoleAuthorityEntity::getAuthorityId).collect(Collectors.toList());
        List<AuthorityEntity> authorityEntityList = collect.stream().map(iter -> {
            AuthorityEntity byId1 = authorityService.getById(iter);
            return byId1;
        }).collect(Collectors.toList());
        List<String> authorityCode = authorityEntityList.stream().map(AuthorityEntity::getAuthorityCode).collect(Collectors.toList());

        //将权限编码通过合并相同key再传给前端。
        // 创建一个 Map 存储 key-value 结果
        Map<String, String> resultMap = new HashMap<>();
        // 遍历 authorityCode 数组
        for (String code : authorityCode) {
            // 按点分割
            String[] split = code.split("\\.");
            // 如果已经存在同名的 key，则将当前值追加到已存在的值后面
            if (resultMap.containsKey(split[0])) {
                String value = resultMap.get(split[0]);
                value += "," + split[1];
                resultMap.put(split[0], value);
            } else {
                // 如果不存在同名的 key，则直接将 key 和 value 存入 resultMap
                resultMap.put(split[0], split[1]);
            }
        }

        RoleAuthorityResp roleAuthorityResp = new RoleAuthorityResp();
        BeanUtils.copyProperties(byId,roleAuthorityResp);
        roleAuthorityResp.setPermissions(resultMap);
        return roleAuthorityResp;
    }
}
